<template>
    <div class="opc_tag_panel">
        <div class="top">
            <el-input
                type="textarea"
                @blur="expressionBlurHandler"
                :rows="2"
                v-model="expression"
                placeholder="请输入文本表达式" />
        </div>
        <div class="bottom">
            <div class="left">
                <div class="outter">
                    <div class="inner">
                        <div class="cell" v-for="opcTag in opcTagUnselectedList" v-bind:key="opcTag.id">
                            <Cell :opcTag="opcTag" @select="selectHandler" />
                        </div>
                    </div>
                </div>
            </div>
            <div class="right">
                <div class="outter">
                    <div class="inner">
                        <div class="cell" v-for="dependency in dependencies" v-bind:key="dependency.key">
                            <CellUnS 
                                :dependency="dependency"
                                :factors="factors"
                                :factorsSelection="factorsSelection"
                                @factorSelect="factorSelectHandler"
                                @unselect="unselectHandler"
                                @up="upHandler"
                                @down="downHandler"/>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import Cell from "./OpcTagCell";
import CellUnS from "./OpcTagCellUnS";
export default {
    components: {
        Cell, CellUnS
    },
    props: ["calItemId"],
    data() {
        return {
            opcTagUnselectedList: [],
            dependencies: [],
            expression: "",
            factors: [],
            factorsSelection: {}
        }
    },
    methods: {
        listOpcTag() {
            let _this = this;
            this.$http.post('/uni/list',
                {
                    modelName: "opcTag",
                    condition: null,
                    orders: [],
                    pagination: null
                }
            )
            .then(function(res){
                _this.opcTagUnselectedList = res.data.data.list;
            })
            .catch(function(error){
                console.log(error);
            });
        },
        /**
         * @param dependencyType    依赖项类型
         * @param dependencyData              依赖项
         */
        selectHandler(dependencyType, dependencyData) {
            let selected = false;
            if(dependencyType == 1) {                       // OPC基础变量
                // 是否已添加
                for(let i = 0; i < this.dependencies.length; i++) {
                    let dependency = this.dependencies[i];
                    if(dependency.dependencyOpcTag.id == dependencyData.id) {
                        selected = true;
                        break;
                    }
                }
                if(!selected) {
                    let dependency = {
                        id: null,
                        // 用于Vue渲染组件唯一键
                        key: dependencyType + "_" + dependencyData.id,
                        mainCalItem: null,
                        dependencyType: dependencyType,
                        dependencyOpcTag: dependencyData,
                        dependencyCalItem: null
                    }
                    this.dependencies.push(dependency);
                }
            } else if(dependencyType == 2) {                // 计算项
                // 是否已添加
                for(let i = 0; i < this.dependencies.length; i++) {
                    let dependency = this.dependencies[i];
                    if(dependency.dependencyCalItem.id == dependencyData.id) {
                        selected = true;
                        break;
                    }
                }
                if(!selected) {
                    let dependency = {
                        id: null,
                        // 用于Vue渲染组件唯一键
                        key: dependencyType + "_" + dependencyData.id,
                        mainCalItem: null,
                        dependencyType: dependencyType,
                        dependencyOpcTag: dependencyData,
                        dependencyCalItem: null
                    }
                    this.dependencies.push(dependency);
                }
            }
        },
        unselectHandler(dependencyUnselected) {
            let newDependencies = [];
            for(let i = 0; i < this.dependencies.length; i++) {
                let dependency = this.dependencies[i];
                if(!this.dependencyEquals(dependencyUnselected, dependency)) {
                    newDependencies.push(dependency);
                } else {
                    if(dependency.factor) {
                        this.factorsSelection[dependency.factor] = null;
                    }
                }
            }
            this.dependencies = newDependencies;
        },
        upHandler(dependencySelected) {
            if(this.dependencies && this.dependencies.length > 1) {
                for(let idx = 1; idx < this.dependencies.length; idx++) {
                    let dependency = this.dependencies[idx];
                    if(this.dependencyEquals(dependencySelected, dependency)) {
                        this.dependencies[idx] = this.dependencies[idx - 1];
                        this.dependencies[idx - 1] = dependencySelected;
                        this.dependencies.splice();
                        break;
                    }
                }
            }
        },
        downHandler(dependencySelected) {
            if(this.dependencies && this.dependencies.length > 1) {
                for(let idx = 0; idx < this.dependencies.length - 1; idx++) {
                    let dependency = this.dependencies[idx];
                    if(this.dependencyEquals(dependencySelected, dependency)) {
                        this.dependencies[idx] = this.dependencies[idx + 1];
                        this.dependencies[idx + 1] = dependencySelected;
                        this.dependencies.splice();
                        break;
                    }
                }
            }
        },
        expressionBlurHandler() {
            let reg =/([a-zA-Z]+[0-9]*|[a-zA-Z]+)/g;
            let newFactors = this.expression.match(reg);
            this.setFactors(newFactors);
        },
        setFactors(newFactors) {
            let newFactorsSelection = {};
            // 保留原有的选择情况
            for(let i = 0; i < newFactors.length; i++) {
                let newFactor = newFactors[i];
                if(this.factorsSelection[newFactor]) {
                    newFactorsSelection[newFactor] = true;
                } else {
                    newFactorsSelection[newFactor] = false;
                }
            }
            this.factors = newFactors;
            this.factorsSelection = newFactorsSelection;
        },
        factorSelectHandler(factor, oldFactor, dependency) {
            // 设置依赖因子
            for(let i = 0; i < this.dependencies.length; i++) {
                if(this.dependencyEquals(this.dependencies[i], dependency)) {
                    this.dependencies[i].factor = factor;
                    break;
                }
            }
            if(factor) {
                this.factorsSelection[factor] = true;
            }
            if(oldFactor) {
                this.factorsSelection[oldFactor] = false;
            }
        },
        /**
         * 判断依赖项相等
         * 
         * @param dependencyX
         * @param dependencyY
         */
        dependencyEquals(dependencyX, dependencyY) {
            let sameDependency = false;
            if(dependencyX && dependencyY &&
                dependencyX.dependencyType == 1 && 
                dependencyY.dependencyType == 1 &&
                dependencyX.dependencyOpcTag &&
                dependencyY.dependencyOpcTag &&
                dependencyX.dependencyOpcTag.id == dependencyY.dependencyOpcTag.id) {
                sameDependency = true;
            } else if(dependencyX && dependencyY &&
                dependencyX.dependencyType == 2 && 
                dependencyY.dependencyType == 2 &&
                dependencyX.dependencyCalItem &&
                dependencyY.dependencyCalItem &&
                dependencyX.dependencyCalItem.id == dependencyY.dependencyCalItem.id) {
                sameDependency = true;
            }
            return sameDependency;
        }
    },
    mounted() {
        this.listOpcTag();
    }
};
</script>

<style lang="less" scoped>

.opc_tag_panel {
    width: 100%;
    height: 100%;
    min-height: 500px;
    display: flex;
    flex-flow: column nowrap;

    .top {
        flex: none;
    }

    .bottom {
        flex: auto;
        display: flex;
        flex-flow: row nowrap;

        .left {
            flex: auto;
            overflow-y: auto;
        
            .outter {
                position: relative;
                width: 100%;

                .inner {
                    position: absolute;
                    left: 0;
                    top: 0;
                    right: 0;
                    bottom: 0;
                }
            }
        }

        .middle {
            flex: none;
            width: 40px;

            .outter {
                position: relative;
                
                .inner {
                    position: absolute;
                    left: 0;
                    top: 0;
                    right: 0;
                    bottom: 0;
                }
            }
        }

        .right {
            flex: auto;
            overflow-y: auto;

            .outter {
                position: relative;
                width: 100%;

                .inner {
                    position: absolute;
                    left: 0;
                    top: 0;
                    right: 0;
                    bottom: 0;
                }
            }
        }
    }
}
</style>